With Vike, you control how your pages are rendered:

```jsx
// /pages/about/+Page.js
// Environment: browser and server

export { Page }

// Vike uses Filesystem Routing: the file `/pages/about/+Page.js` matches the URL `/about`.

// `Page` can be anything you want — typically a React/Vue/Svelte/... component.
function Page() {
  return <>
    <h1>About</h1>
    <p>This is our first Vike app.</p>
  </>
}
```

```js
// /renderer/+onRenderHtml.js
// Environment: server

export { onRenderHtml }

import { escapeInject, dangerouslySkipEscape } from 'vike/server'
// This can be any UI framework (React, Vue, Svelte, ...)
import { renderToHtml } from 'my-favorite-ui-framework'

// You control how `Page` is rendered to HTML
async function onRenderHtml({ Page }) {
  const pageHtml = await renderToHtml(Page)
  const title = 'My first Vike app'
  return escapeInject`<!DOCTYPE html>
    <html>
      <head>
        <title>{title}</title>
      </head>
      <body>
        <div id="page-root">${dangerouslySkipEscape(pageHtml)}</div>
      </body>
    </html>`
}
```

```js
// /renderer/+onRenderClient.js
// Environment: browser

export { onRenderClient }

import { hydrateDom } from 'my-favorite-ui-framework'

// You control how `Page` is hydrated
async function onRenderClient({ Page }) {
  await hydrateDom(Page)
}
```

This level of control means you can use and integrate any tool you want.
